<template>
  <div 
    class="animated-background"
    :style="{ 
      background: backgroundStyle, 
      opacity: opacity
    }"
  >
    <canvas 
      ref="noiseCanvas" 
      class="noise-canvas"
      :style="{ opacity: noiseOpacity }"
    ></canvas>
    <div class="overlay" v-if="overlay"></div>
  </div>
</template>

<script>
export default {
  name: 'AnimatedBackground',
  props: {
    color1: {
      type: String,
      default: '#4361ee'
    },
    color2: {
      type: String,
      default: '#3a0ca3'
    },
    angle: {
      type: Number,
      default: 135
    },
    animated: {
      type: Boolean,
      default: true
    },
    speed: {
      type: Number,
      default: 0.3
    },
    opacity: {
      type: Number,
      default: 1
    },
    noiseOpacity: {
      type: Number,
      default: 0.05
    },
    overlay: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      hue: 0,
      noise: null,
      ctx: null,
      animationId: null,
      isRunning: false
    }
  },
  computed: {
    backgroundStyle() {
      if (this.animated) {
        return `linear-gradient(${this.angle}deg, ${this.color1}, ${this.color2})`;
      } else {
        return `linear-gradient(${this.angle}deg, ${this.color1}, ${this.color2})`;
      }
    }
  },
  mounted() {
    if (this.animated) {
      this.initCanvas();
      this.start();
    }
  },
  beforeUnmount() {
    this.stop();
  },
  methods: {
    initCanvas() {
      const canvas = this.$refs.noiseCanvas;
      if (!canvas) return;
      
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
      this.ctx = canvas.getContext('2d');
      
      // 创建噪声
      this.createNoise();
      
      // 窗口大小变化时重绘
      window.addEventListener('resize', this.handleResize);
    },
    
    handleResize() {
      const canvas = this.$refs.noiseCanvas;
      if (!canvas) return;
      
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
      
      this.createNoise();
    },
    
    createNoise() {
      const canvas = this.$refs.noiseCanvas;
      const ctx = this.ctx;
      
      // 创建噪声纹理
      const imageData = ctx.createImageData(canvas.width, canvas.height);
      const data = imageData.data;
      
      for (let i = 0; i < data.length; i += 4) {
        // 随机灰度值
        const value = Math.floor(Math.random() * 255);
        data[i] = value; // r
        data[i + 1] = value; // g
        data[i + 2] = value; // b
        data[i + 3] = 100; // alpha 
      }
      
      this.noise = imageData;
      ctx.putImageData(imageData, 0, 0);
    },
    
    start() {
      if (this.isRunning) return;
      
      this.isRunning = true;
      this.animate();
    },
    
    stop() {
      this.isRunning = false;
      if (this.animationId) {
        cancelAnimationFrame(this.animationId);
        this.animationId = null;
      }
      
      window.removeEventListener('resize', this.handleResize);
    },
    
    animate() {
      if (!this.isRunning) return;
      
      this.animationId = requestAnimationFrame(this.animate);
      
      // 更新渐变色彩
      this.hue = (this.hue + this.speed) % 360;
      
      // 移动噪声
      this.updateNoise();
    },
    
    updateNoise() {
      if (!this.ctx || !this.noise) return;
      
      const canvas = this.$refs.noiseCanvas;
      const ctx = this.ctx;
      
      // 获取当前噪声数据
      const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
      const data = imageData.data;
      
      // 移动噪声 - 简单的扰动效果
      for (let i = 0; i < data.length; i += 4) {
        if (Math.random() > 0.96) {
          data[i] = Math.floor(Math.random() * 255);
          data[i + 1] = data[i];
          data[i + 2] = data[i];
        }
      }
      
      ctx.putImageData(imageData, 0, 0);
    }
  }
}
</script>

<style scoped>
.animated-background {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  z-index: -2;
  background-size: 400% 400%;
}

.noise-canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  mix-blend-mode: overlay;
  z-index: -1;
}

.overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-image: radial-gradient(rgba(0, 0, 0, 0) 1px, rgba(0, 0, 0, 0.03) 1px);
  background-size: 4px 4px;
  backdrop-filter: blur(3px);
  z-index: -1;
}

@keyframes gradient {
  0% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0% 50%;
  }
}
</style> 